/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cidetec.controlador;

//import com.cidetec.modelado.LibroDataModel;
import com.cidetec.business.AdminSubirArchivoBusiness;
import com.cidetec.modelo.entidad.Libro;
import com.cidetec.modelo.entidad.LibroReferencia;
import com.cidetec.modelo.entidad.LibroUbicacion;
import com.cidetec.utils.Constantes;
import com.cidetec.utils.LazySorterLibro;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Carlos
 */
@ManagedBean(name = "adminSubirArchivoController")
@ViewScoped
public class AdminSubirArchivoController {

    private final static Logger logger = LoggerFactory.getLogger(AdminSubirArchivoController.class);

    @ManagedProperty("#{AdminSubirArchivoBusiness}")
    transient AdminSubirArchivoBusiness librosBusiness;

    private List<Libro> crearLibrosFromExcel;

    private LazyDataModel<Libro> lazyDataModel;

    public AdminSubirArchivoController() {
        crearLibrosFromExcel = null;
    }

    public void subirArchivoExecute(FileUploadEvent event) {
        try {
            InputStream inputstream = event.getFile().getInputstream();
            crearLibrosFromExcel = librosBusiness.crearLibrosFromExcel(inputstream);
            logger.debug("Tamaño de los libros {}", crearLibrosFromExcel.size());
            switch (librosBusiness.getCodigo()) {
                case Constantes.CODIGO_BIEN:
                    FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_INFO, "IPN-CIDETEC Mensaje", "¡Bien! Usuario dado de alta exitosamente"));
                    break;
                case Constantes.CODIGO_ERROR:
                    FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "IPN-CIDETEC Mensaje", "¡Error! Consulte a soporte tecnico"));
                    break;
            }
        } catch (IOException ex) {
            logger.debug("Error al crear el flujo del libro, descripcion: {}", ex);
        }
        lazyDataModel = new LazyDataModel<Libro>() {
            List<Libro> datasource = crearLibrosFromExcel;

            @Override
            public Libro getRowData(String rowKey) {
                for (Libro libro : datasource) {
                    if (libro.getCodigoBarras().equals(rowKey)) {
                        return libro;
                    }
                }
                return null;
            }

            @Override
            public List<Libro> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                List<Libro> data = new ArrayList<Libro>();

                //filter  
                for (Libro libro : datasource) {
                    boolean match = true;
                    for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                        try {
                            String filterProperty = it.next();
                            Field field;
                            String filterValue = "";
                            String fieldValue;
                            if (filterProperty.contains("libroReferencia")) {
                                filterValue = filters.get(filterProperty);
                                filterProperty = filterProperty.replace("libroReferencia.", "");
                                LibroReferencia libroReferencia = libro.getLibroReferencia();
                                field = libroReferencia.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(libroReferencia));
                            } else if (filterProperty.contains("libroUbicacion.")) {
                                filterValue = filters.get(filterProperty);
                                filterProperty = filterProperty.replace("libroUbicacion.", "");
                                LibroUbicacion libroUbicacion = libro.getLibroUbicacion();
                                field = libroUbicacion.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(libroUbicacion));
                            } else {
                                field = libro.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                filterValue = filters.get(filterProperty);
                                fieldValue = String.valueOf(field.get(libro));
                            }
                            if (filterValue == null || fieldValue.contains(filterValue)) {
                                match = true;
                            } else {
                                match = false;
                                break;
                            }
                        } catch (Exception e) {
                            match = false;
                        }
                    }

                    if (match) {
                        data.add(libro);
                    }
                }

//                sort  
                if (sortField != null) {
                    Collections.sort(data, new LazySorterLibro(sortField, sortOrder));
                }
                if (sortField == null) {
                    sortField = "defaultSortField";
                }
                //rowCount  
                int dataSize = data.size();
                this.setRowCount(dataSize);

                //paginate  
                if (dataSize > pageSize) {
                    try {
                        return data.subList(first, first + pageSize);
                    } catch (IndexOutOfBoundsException e) {
                        return data.subList(first, first + (dataSize % pageSize));
                    }
                } else {
                    return data;
                }
            }

            @Override
            public Object getRowKey(Libro t) {
                return t.getCodigoBarras();
            }
        };
    }

    public void createLibroExecute() {
        librosBusiness.createLibro(crearLibrosFromExcel);
        switch (librosBusiness.getCodigo()) {
            case Constantes.CODIGO_BIEN:
                FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_INFO, "IPN-CIDETEC Mensaje", "¡Bien! Usuario dado de alta exitosamente"));
                break;
            case Constantes.CODIGO_ERROR:
                FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "IPN-CIDETEC Mensaje", "¡Error! Consulte a soporte tecnico"));
                break;
        }
    }

    public void setLibrosBusiness(AdminSubirArchivoBusiness librosBusiness) {
        this.librosBusiness = librosBusiness;
    }

    public List<Libro> getCrearLibrosFromExcel() {
        return crearLibrosFromExcel;
    }

    public void setCrearLibrosFromExcel(List<Libro> crearLibrosFromExcel) {
        this.crearLibrosFromExcel = crearLibrosFromExcel;
    }

    public LazyDataModel<Libro> getLazyDataModel() {
        return lazyDataModel;
    }

    public void setLazyDataModel(LazyDataModel<Libro> lazyDataModel) {
        this.lazyDataModel = lazyDataModel;
    }

}
